#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>

#define PORT 3490 		/* Server的端口 */
#define MAXDATASIZE 100	/*一次可以读的最大字节数 */
float a;
float cpu_use; 
typedef struct PACKED
{
char name[20];      //定义一个char类型的数组名name有20个元素
float user; //定义一个无符号的int类型的user
float nice; //定义一个无符号的int类型的nice
float system;//定义一个无符号的int类型的system
float idle; //定义一个无符号的int类型的idle
float iowait;
float irq;
float softirq;
}CPU_OCCUPY;

float cal_cpuoccupy (CPU_OCCUPY *o, CPU_OCCUPY *n)
{  
    unsigned long od, nd;   
    unsigned long id, sd;
     
   
    od = (float) (o->user + o->nice + o->system +o->idle+o->iowait+o->irq+o->softirq);	//第一次时间再赋给od
    nd = (float) (n->user + n->nice + n->system +n->idle+n->iowait+n->irq+n->softirq);  //第二次时间再赋给nd
     
    id = (float) (n->user - o->user);  //用户第一次和第二次的时间之差再赋给id
    sd = (float) (n->system - o->system);//系统第一次和第二次的时间之差再赋给sd
    if((nd-od) != 0)
    cpu_use = (float)((sd+id)*100)/(nd-od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used
    else cpu_use = 0;
    return cpu_use;
}

get_cpuoccupy (CPU_OCCUPY *cpust) //对无类型get函数含有一个形参结构体类弄的指针cpust
{  
    FILE *fd;        //定义文件指针fd
    float n;         //定义局部变量n为float类型  
    char buff[256];  //定义局部变量buff数组为char类型大小为1024
    CPU_OCCUPY *cpu_occupy;
    cpu_occupy=cpust;
                                                                                                              
    fd = fopen ("/proc/stat", "r");//以R读的方式打开stat文件再赋给指针fd
    fgets (buff, sizeof(buff), fd);//从fd文件中读取长度为buff的字符串再存到起始地址为buff这个空间里
   
    sscanf (buff, "%s %f %f %f %f %f %f %f", cpu_occupy->name, &cpu_occupy->user, &cpu_occupy->nice, &cpu_occupy->system,  &cpu_occupy->idle, &cpu_occupy->iowait, &cpu_occupy->irq, &cpu_occupy->softirq);
   
    fclose(fd);    //关闭文件fd
}

float neicun()
{
	FILE *fp;
	char mem[10];
	float meminfo[2];
	float mem_rate;
	char text[1024];
	fp=fopen("/proc/meminfo","r");
	int index=0;
	while(!feof(fp))
	{
		if(index<2)
		{		
			fgets(text,1024,fp);	
			sscanf(text,"%s %f\n",mem,&meminfo[index]);
			index++;
		}
		else break;
		
	}
	fclose(fp);
	mem_rate=(1-meminfo[1]/meminfo[0])*100;
	a=mem_rate;
	sleep(3);
	return (a);
}

int main(int argc, char *argv[])
{
 	int numbytes,sockfd;
	char ch;
	char buf[100];
	float neicun();
	struct hostent*he;		/* 主机信息 */
	struct sockaddr_in their_addr; 	/* 对方地址信息 */
	if (argc != 2) {
		fprintf(stderr,"usage: client hostname\n");
		exit(1);
	}
	if ((he=gethostbyname(argv[1])) == NULL) { 
		/* get the host info */
		herror("gethostbyname");
		exit(1);
	}

	if ((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {
		perror("socket");
		exit(1);
	}
	
	their_addr.sin_family = AF_INET; 
	their_addr.sin_port = htons(PORT); 		/* short, NBO */
	their_addr.sin_addr = *((struct in_addr *)he->h_addr);
	bzero(&(their_addr.sin_zero), 8); 		/* 其余部分设成0 */

	if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
		perror("connect");
		exit(1);
	}
	while(1)
{	

    CPU_OCCUPY cpu_stat1;
    CPU_OCCUPY cpu_stat2;
    float cpu; 

    get_cpuoccupy((CPU_OCCUPY *)&cpu_stat1);    //第一次获取cpu使用情况
    sleep(3);

    get_cpuoccupy((CPU_OCCUPY *)&cpu_stat2);    //第二次获取cpu使用情况
   
    //计算cpu使用率
    	cpu = cal_cpuoccupy ((CPU_OCCUPY *)&cpu_stat1, (CPU_OCCUPY *)&cpu_stat2);
	printf("%f\n",cpu_use);
        sprintf(buf,"%f",cpu_use); 
    	if (send(sockfd,buf, sizeof(buf), 0) == -1) perror("send");
   	neicun();
	printf("%f\n",a);
        sprintf(buf,"%f",a); 
     	if (send(sockfd,buf, sizeof(buf), 0) == -1) perror("send");
	sleep(3); 
}
	close(sockfd);
	return 0;
}

